import re
from flask import current_app, jsonify
from flask import g
from flask import json
from flask import request
from flask import session
from api_v1.models import Area, Facility, House, HouseImage, Order
from api_v1 import redis_store, db
from api_v1.utils.my_decorators import user_login_data
from api_v1.utils.qiniu_sdk import put_qiniu

from . import house_blue
from api_v1.utils.response_code import RET, ret_map


def get_area():
    """查询地区数据并缓存redis"""
    area_dict_list = redis_store.get('area_list')

    if not area_dict_list:
        try:
            area_list = Area.query.all()
        except Exception as e:
            current_app.logging.error('查询数据库出错')
            return jsonify(code=RET.DBERR, msg=ret_map[RET.DBERR])
        area_dict_list = [i.to_dict() for i in area_list]

        # 将数据缓存进redis
        redis_store.set('area_list', json.dumps(area_dict_list))
    else:
        area_dict_list = json.loads(area_dict_list)

    return area_dict_list


def get_facility():
    """查询设施数据并缓存redis"""
    facility_dict_list = redis_store.get('facility_list')
    if not facility_dict_list:
        try:
            facility_list = Facility.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(code=RET.DBERR, msg=ret_map[RET.DBERR])
        facility_dict_list = [i.to_dict() for i in facility_list]

        # 将数据缓存进redis
        redis_store.set('facility_list', json.dumps(facility_dict_list))

    else:
        facility_dict_list = json.loads(facility_dict_list)

    return facility_dict_list


# 请求路径: /api/v1/house/area_facility
# 请求方式: GET
# 请求参数:
# 返回值:area facility
@house_blue.route("/area_facility")
def newhouse():
    """查询地区和设施"""  # 地区和房屋设施
    # 查询地区
    area_dict_list = get_area()

    # 查询设施
    facility_dict_list = get_facility()

    return jsonify(area=area_dict_list, facility=facility_dict_list)


@house_blue.route('/')
@user_login_data
def myhouse():
    """查看当前用户的房源信息"""
    # 1.判断用户是否进行实名认证,
    if g.user.id_name:
        try:
            # 已经实名认证,查询当前用户的房屋信息
            house_list = House.query.filter(House.user_id == g.user.id).order_by(House.id.desc()).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(code=RET.DBERR, msg=ret_map[RET.DBERR])

        # 2.查看当前用户的房屋信息
        new_house_list = []
        for i in house_list:
            new_house_list.append(i.to_dict())

        # 3.返回成功
        return jsonify(code=RET.OK, hlist=new_house_list)

    else:
        # 返回当前用户没有进行实名认证
        return jsonify(code=RET.USERERR)


@house_blue.route('/<int:id>', methods=['GET'])
def house_detail(id):
    # 查询房屋详情
    house = House.query.get(id)
    # 查询设施信息
    facility_list = get_facility()
    # 判断当前房屋信息是否为当前登录的用户发布，如果是则不显示预定按钮，用户未登录则不显示预定按钮
    booking = 1
    if 'user_id' in session:
        if house.user_id == session['user_id']:
            booking = 0
    else:
        booking = 0

    return jsonify(house=house.to_full_dict(),
                   facility_list=facility_list,
                   booking=booking)


# 首頁展示最新五個房屋
@house_blue.route("/index")
@user_login_data
def index():
    # 返回前端用戶登陸判斷依據
    user_name = ""
    code = RET.LOGINERR
    if g.user:
        user_name = g.user.name
        code = RET.OK
    # 從redis中獲取最新５個房屋的信息
    hlist2 = redis_store.get("hlist")
    if not hlist2:
        hlist = House.query.order_by(House.create_time.desc())[:5]
        hlist2 = [house.to_dict() for house in hlist]
        redis_store.set('hlist',json.dumps(hlist2),24*3600)
    else:
        hlist2 = json.loads(hlist2)
    # 查找地區信息
    alist = get_area()
    return jsonify(code=code,name=user_name,hlist=hlist2,alist=alist)


@house_blue.route('/', methods=['POST'])
@user_login_data
def newhouse_save():
    """发布新房源"""
    # 1 获取参数
    user = g.user
    data_dict = request.form.to_dict()
    title = data_dict.get('title')  # 房屋标题
    price = data_dict.get('price')  # 每晚价格
    area_id = data_dict.get('area_id')  # 所在城区
    address = data_dict.get('address')  # 详细地址
    room_count = data_dict.get('room_count')  # 出租房间数
    acreage = data_dict.get('acreage')  # 房屋面积
    unit = data_dict.get('unit')  # 户型描述
    capacity = data_dict.get('capacity')  # 宜居人数
    beds = data_dict.get('beds')  # 卧床配置
    deposit = data_dict.get('deposit')  # 押金数额
    min_days = data_dict.get('min_days')  # 最少入住天数
    max_days = data_dict.get('max_days')  # 最多入住天数
    # 获取配套设施，返回一个列表
    facility_ids = request.form.getlist('facility')

    # 2.检验参数
    if not all(
            [title, price, area_id, address, room_count, acreage, unit, capacity, beds, deposit, min_days, max_days]):
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])

    try:
        price = int(price)
        deposit = int(deposit)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])

    # 3 创建数据
    house = House()
    house.user_id = user.id
    house.area_id = area_id
    house.title = title
    house.price = price
    house.address = address
    house.room_count = room_count
    house.acreage = acreage
    house.unit = unit
    house.capacity = capacity
    house.beds = beds
    house.deposit = deposit
    house.min_days = min_days
    house.max_days = max_days

    if facility_ids:
        facilities = Facility.query.filter(Facility.id.in_(facility_ids)).all()
        house.facilities = facilities

    try:
        db.session.add(house)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(code=RET.DBERR, msg=ret_map[RET.DBERR])

    # 更新redis中的五条房屋信息
    hlist = House.query.order_by(House.id.desc()).limit(5)
    hlist2 = [house.to_dict() for house in hlist]
    redis_store.setex('hlist', 24*3600, json.dumps(hlist2))

    # 6.返回数据
    return jsonify(code=RET.OK, house_id=house.id)


# 房屋图片展示# 请求路径: /api/v1/house//image
# 请求方式: POST0.
# 请求参数:house_id,house_image
# 返回值:area facility
@house_blue.route("/image",methods=['POST'])
def home_image():
    #1获取参数
    house_id=request.form.get('house_id')
    house_image=request.files.get('house_image')
    # 2验证参数
    # 判断是否空值
    if not all([house_id,house_image]):
        return jsonify(code=RET.PARAMERR, msg='参数不齐')
    # 判断图片格式是否正确
    if not re.match('image/.*', house_image.mimetype):
        return jsonify(code=RET.PARAMERR, msg='格式错误')
    # 3 上传图片到七牛云
    image_url = put_qiniu(house_image)
    # avatar_url = put_qiniu(file_content)
    # 4创建house_image图片对象
    image = HouseImage()
    image.house_id = house_id
    image.url =image_url
    # 5设置房屋图片
    # 查询房子
    try:
        house = House.query.get(house_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DATAERR,msg=ret_map[RET.DATAERR])
    # 设置房屋图片
    if not house.index_image_url:
        house.index_image_url=image_url
        house.add_update()
    # 把最新的五条房屋数据更新到redis中
    hlist = House.query.order_by(House.create_time.desc())[:5]
    hlist2 = [house.to_dict() for house in hlist]
    redis_store.setex('hlist', 24 * 3600, json.dumps(hlist2))
    # 6返回图片的信息
    return jsonify(code=RET.OK,url=current_app.config.get('QINIU_URL') + image_url)


@house_blue.route('/search', methods=['GET'])
def search():

    # 接收参数
    data_dict = request.args
    area_id=data_dict.get('aid')
    start_date=data_dict.get('sd')
    end_date=data_dict.get('ed')
    sort_key=data_dict.get('sk')

    # 检验参数
    if not area_id:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    # 满足地区条件
    hlist=House.query.filter(House.area_id==area_id)
    #不能查询自己发布的房源，排除当前用户发布的房屋
    if 'user_id' in session:
        hlist=hlist.filter(House.user_id!=(session['user_id']))
    #满足时间条件，当订单完成后再完成时间限制
    order_list=Order.query.filter(Order.status!='REJECTED')
    #情况一：
    # order_list1=Order.query.filter(Order.begin_date>=begin_date,Order.end_date<=end_date)
    #情况二：
    order_list2=order_list.filter(Order.begin_date<start_date,Order.end_date>end_date)
    #情况三：
    order_list3=order_list.filter(Order.end_date>=start_date,Order.end_date<=end_date)
    #情况四：
    order_list4=order_list.filter(Order.begin_date>=start_date,Order.begin_date<=end_date)
    #获取订单中的房屋编号start_date
    house_ids=[order.house_id for order in order_list2]#[1,2,3]
    for order in order_list3:
        house_ids.append(order.house_id)
    for order in order_list4:
        if order.house_id not in house_ids:
            house_ids.append(order.house_id)
    hlist=hlist.filter(House.id.notin_(house_ids))
    #排序规则,默认根据最新排列
    sort=House.id.desc()
    if sort_key=='booking':
        sort=House.order_count.desc()
    elif sort_key=='price-inc':
        sort=House.price.asc()
    elif sort_key=='price-des':
        sort=House.price.desc()
    hlist=hlist.order_by(sort)
    hlist2=[]
    for house in hlist:
        hlist2.append(house.to_dict())
    #获取地区信息
    if request.args.get('area','0')=='1':
        alist=get_area()
    else:
        alist=[]
    return jsonify(hlist=hlist2,alist=alist)